package com.tools.scanner.ui.qrcode.creator

import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.tools.scanner.BaseActivity
import com.tools.scanner.R
import com.tools.scanner.bean.BarcodeSchema
import com.tools.scanner.databinding.ActivitySelectCreateQrCodeBinding
import com.tools.scanner.databinding.RecyclerSelectQrcodeItemBinding
import com.tools.scanner.databinding.RecyclerSelectQrcodeTitleBinding
import java.io.Serializable

class SelectCrateQrCodeActivity : BaseActivity() {

    companion object {
        fun actionStart(context: Context) {
            val intent = Intent(context, SelectCrateQrCodeActivity::class.java)
            context.startActivity(intent)
        }
    }

    private lateinit var mBinding: ActivitySelectCreateQrCodeBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = ActivitySelectCreateQrCodeBinding.inflate(layoutInflater)
        setContentView(mBinding.root)

        mBinding.ivBack.setOnClickListener {
            finish()
        }

        val itemInfoList = getDataList()
        mBinding.recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
            private val margin = resources.getDimension(R.dimen.dp_10).toInt()

            override fun getItemOffsets(outRect: Rect, itemPosition: Int, parent: RecyclerView) {
                super.getItemOffsets(outRect, itemPosition, parent)
                outRect.left = margin
                outRect.right = margin
                outRect.bottom = margin
            }
        })
        mBinding.recyclerView.layoutManager = LinearLayoutManager(this)
        mBinding.recyclerView.adapter = QrCodeAdapter(itemInfoList, object : OnClickListener {
            override fun onClick(itemInfo: QrCodeInfo, isClipboard: Boolean) {
                InputContentActivity.actionStart(
                    this@SelectCrateQrCodeActivity,
                    itemInfo.schema
                )
            }
        })
    }

    private fun getDataList(): Pair<List<QrCodeInfo>, List<QrCodeInfo>> {
        val qrDataList = mutableListOf<QrCodeInfo>()

        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_text,
                R.string.scan_type_content,
                schema = BarcodeSchema.TEXT
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_wifi,
                R.string.scan_type_wifi,
                schema = BarcodeSchema.WIFI
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_contact,
                R.string.scan_type_contact,
                schema = BarcodeSchema.CONTACT
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_link,
                R.string.scan_type_link,
                schema = BarcodeSchema.URL
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_sms,
                R.string.scan_type_sms,
                schema = BarcodeSchema.SMS
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_email,
                R.string.scan_type_email,
                schema = BarcodeSchema.EMAIL
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_calendar,
                R.string.scan_type_calendar,
                schema = BarcodeSchema.CALENDER
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_phone,
                R.string.scan_type_phone,
                schema = BarcodeSchema.PHONE
            )
        )
        qrDataList.add(
            QrCodeInfo(
                R.drawable.ic_location,
                R.string.scan_type_geo,
                schema = BarcodeSchema.GEO
            )
        )

        val barcodeDataList = mutableListOf<QrCodeInfo>()

        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.data_matrix,
                schema = BarcodeSchema.DATA_MATRIX
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.aztec,
                schema = BarcodeSchema.AZTEC
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.PDF417,
                schema = BarcodeSchema.PDF_417
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.ean_13,
                schema = BarcodeSchema.EAN_13
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.ean_8,
                schema = BarcodeSchema.EAN_8
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.upc_e,
                schema = BarcodeSchema.UPC_E
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.upc_a,
                schema = BarcodeSchema.UPC_A
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.code_128,
                schema = BarcodeSchema.CODE_128
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.code_93,
                schema = BarcodeSchema.CODE_93
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.code_39,
                schema = BarcodeSchema.CODE_39
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.codabar,
                schema = BarcodeSchema.CODABAR
            )
        )
        barcodeDataList.add(
            QrCodeInfo(
                R.drawable.ic_barcode,
                R.string.itf,
                schema = BarcodeSchema.ITF
            )
        )

        return Pair(qrDataList, barcodeDataList)
    }
}

private class QrCodeAdapter(
    private val itemInfoPair: Pair<List<QrCodeInfo>, List<QrCodeInfo>>,
    private val mListener: OnClickListener
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        private const val QR_TITLE = 1
        private const val QR_ITEM = 2
        private const val BARCODE_TITLE = 3
        private const val BARCODE_ITEM = 4
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)

        if (viewType == QR_TITLE || viewType == BARCODE_TITLE) {
            val binding = RecyclerSelectQrcodeTitleBinding.inflate(layoutInflater, parent, false)
            return TitleViewHolder(binding)
        } else {
            val binding = RecyclerSelectQrcodeItemBinding.inflate(layoutInflater, parent, false)
            return QrCodeViewHolder(binding, mListener)
        }
    }

    override fun getItemCount(): Int {
        return itemInfoPair.first.size + itemInfoPair.second.size + 2
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val viewType = getItemViewType(position)
        if (viewType == QR_TITLE || viewType == BARCODE_TITLE) {
            (holder as TitleViewHolder).refresh(viewType)
            return
        }

        if (holder is QrCodeViewHolder) {

            val itemInfo = if (viewType == QR_ITEM) {
                itemInfoPair.first[position - 1]
            } else {
                itemInfoPair.second[position - itemInfoPair.first.size - 2]
            }

            holder.refresh(itemInfo)
        }
    }

    override fun getItemViewType(position: Int): Int {
        if (position == 0) {
            return QR_TITLE
        }

        if (position - 1 < itemInfoPair.first.size) {
            return QR_ITEM
        }

        if (position - 1 == itemInfoPair.first.size) {
            return BARCODE_TITLE
        }

        return BARCODE_ITEM
    }

    private class TitleViewHolder(
        private val mBinding: RecyclerSelectQrcodeTitleBinding
    ) : RecyclerView.ViewHolder(mBinding.root) {

        fun refresh(viewType: Int) {
            if (viewType == QR_TITLE) {
                mBinding.root.setText(R.string.create_qr_code)
            } else {
                mBinding.root.setText(R.string.create_other_code)
            }
        }

    }

    private class QrCodeViewHolder(
        private val mBinding: RecyclerSelectQrcodeItemBinding,
        private val mListener: OnClickListener
    ) : RecyclerView.ViewHolder(mBinding.root) {

        fun refresh(itemInfo: QrCodeInfo) {
            mBinding.ivType.setImageResource(itemInfo.icon)
            mBinding.tvTitle.setText(itemInfo.content)
            mBinding.root.setOnClickListener {
                mListener.onClick(itemInfo)
            }
        }

    }
}

private interface OnClickListener {
    fun onClick(itemInfo: QrCodeInfo, isClipboard: Boolean = false)
}

data class QrCodeInfo(
    val icon: Int,
    val content: Int,
    val schema: BarcodeSchema
) : Serializable